#include "GetAccessorBuilder.h"

#include "ScriptCompiler/ScriptFileContext.h"
#include "ScriptCompiler/ASTBuilder/SentenceBlockBuilder.h"
#include "ScriptCompiler/ASTBuilder/ExpressionBuilder.h"
#include "ScriptCompiler/AST/GetAccessorNode.h"


CGetAccessorBuilder::CGetAccessorBuilder(std::shared_ptr<CScriptFileContext> InContext)
{
    Context = InContext;
    Result = std::make_shared<CGetAccessorNode>(Context);
}

bool CGetAccessorBuilder::ReadCurentToken()
{
    //check and skip 'get'
    if(Context->GetCurrentToken()->Type != EScriptTokenType::Get)
    {
        Context->RaiseError(10061,Context->GetCurrentToken(),U"Expected 'get' keyword");
        return false;
    }
    Result->GetKeyword = Context->GetCurrentToken();
    Context->CurrentTokenIndex++;

    //build Content
    {
        //check '{'  or '=>'
        auto Token = Context->GetCurrentToken();
        if (Token->Type == EScriptTokenType::LeftBrace)
        {
            Context->CurrentTokenIndex++; //skip '{'

            //find '}'
            auto RightBraceIndex = FindPairedBrace(Context);
            if (!RightBraceIndex)
            {
                //raise error
                Context->RaiseError(10162,Token,U"cant find paired '}'");
                return false;
            }

            auto SentenceBlockBuilder = std::make_shared<CSentenceBlockBuilder>(Context,RightBraceIndex.GetValue());
            
            if (!SentenceBlockBuilder->ReadCurentToken())
            {
                return false;
            }
            Result->Content = SentenceBlockBuilder->Result;

            Token = Context->GetCurrentToken();
            assert (Token->Type == EScriptTokenType::RightBrace);
            Context->CurrentTokenIndex++; //skip '}'

            return true; //finished;

        }
        else if (Token->Type == EScriptTokenType::LambdaOperator)
        {
            Context->CurrentTokenIndex++; //skip '=>'

            //find ';'
            auto SemicolonIndex = FindNextToken(EScriptTokenType::Semicolon,Context);

            if (!SemicolonIndex)
            {
                //raise Error
                Context->RaiseError(10163,Token,U"cant find ';' as end of statement after =>");
                return false;
            }

            auto LambdaBuilder = std::make_shared<CSentenceBlockBuilder>(Context,SemicolonIndex.GetValue());
            if (!LambdaBuilder->ReadCurentToken())
            {
                return false;
            }
            Result->LambdaContent = LambdaBuilder->Result;

            //skip ;
            assert(Context->GetCurrentToken()->Type==EScriptTokenType::Semicolon);
            Context->CurrentTokenIndex++;

            return true; //finished;
        }
        else
        {
            Context->RaiseError(10063,Token,U"Expected '{' or '=>' after 'get' keyword");
            return false;
        }


    }

}
